package net.wicp.tams.common.binlog.alone;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.Validate;

import lombok.extern.slf4j.Slf4j;
import net.wicp.tams.common.Conf;
import net.wicp.tams.common.apiext.StringUtil;
import net.wicp.tams.common.binlog.alone.ListenerConf.ConnConf;
import net.wicp.tams.common.binlog.alone.ListenerConf.ConnConf.Builder;
import net.wicp.tams.common.binlog.alone.ListenerConf.HaType;
import net.wicp.tams.common.binlog.alone.ListenerConf.Position;
import net.wicp.tams.common.binlog.alone.parser.ParseLogOnline;

@Slf4j
public abstract class BusiAssit {

	/***
	 * 通过配置文件启动监听
	 */
	public static void startListenerForConfig() {
		List<ConnConf.Builder> confs = ConfigInit();
		for (Builder conf : confs) {
			BinlogStart.listeningNonBlocking(conf);
		}

		ScheduledExecutorService timerService = Executors.newSingleThreadScheduledExecutor();
		// 第二个参数为首次执行的延时时间，第三个参数为定时执行的间隔时间
		ScheduledFuture<?> scheduleAtFixedRate = timerService.scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				List<Thread> startThreadList = ParseLogOnline.startThreadList;
				for (Thread startThread : startThreadList) {
					log.info("the listener:{} isAlive:{}", startThread.getName(), startThread.isAlive());
				}
			}
		}, 10, 10, TimeUnit.SECONDS);

	}

	public static Map<String, Map<String, String>> getConfigMap() {
		Map<String, Map<String, String>> preGroups = Conf.getPreGroup("common.binlog.alone.conf");
		return preGroups;
	}

	public static ConnConf.Builder configMap(String configKey, Map<String, String> map) {
		Validate.notBlank(configKey, "binlog监听配置项configKey不能为空");
		Validate.isTrue(MapUtils.isNotEmpty(map), "binlog监听map参数不能为空");
		Builder newBuilder = ConnConf.newBuilder();
		newBuilder.setConfName(configKey);
		if (StringUtil.isNotNull(map.get("ip"))) {
			newBuilder.setIp(map.get("ip"));
		}
		if (StringUtil.isNotNull(map.get("user"))) {
			newBuilder.setUser(map.get("user"));
		}
		if (StringUtil.isNotNull(map.get("password"))) {
			newBuilder.setPassword(map.get("password"));
		}
		if (StringUtil.isNotNull(map.get("listener"))) {
			newBuilder.setListener(map.get("listener"));
		}
		if (StringUtil.isNotNull(map.get("port"))) {
			newBuilder.setPort(Integer.parseInt(map.get("port")));
		}
		if (StringUtil.isNotNull(map.get("rds"))) {
			newBuilder.setRds(Boolean.parseBoolean(map.get("rds")));
		}
		if (StringUtil.isNotNull(map.get("chk"))) {
			newBuilder.setChk(map.get("chk"));
		}
		if (StringUtil.isNotNull(map.get("dbPattern"))) {
			newBuilder.setDbPattern(map.get("dbPattern"));
		}
		if (StringUtil.isNotNull(map.get("tbPattern"))) {
			newBuilder.setTbPattern(map.get("tbPattern"));
		}
		if (StringUtil.isNotNull(map.get("clientId"))) {
			newBuilder.setClientId(Integer.parseInt(map.get("clientId")));
		}
		if (StringUtil.isNotNull(map.get("groupId"))) {
			newBuilder.setGroupId(map.get("groupId"));
		}
		if (StringUtil.isNotNull(map.get("haType"))) {
			HaType haType = HaType.valueOf(HaType.class, map.get("haType"));
			if (haType == null) {
				haType = HaType.cur;
			}
			newBuilder.setHaType(haType);
		}
		// 位置，暂时只支持gtids
		if (StringUtil.isNotNull(map.get("pos.gtids"))) {
			Position.Builder posBuilder = Position.newBuilder().setGtids(map.get("pos.gtids"));
			newBuilder.setPos(posBuilder);
		}
		return newBuilder;
	}

	public static ConnConf.Builder configMap(String configKey) {
		Map<String, String> map = Conf.getPre("common.binlog.alone.conf." + configKey, true);
		return configMap(configKey, map);
	}

	public static List<ConnConf.Builder> ConfigInit() {
		Map<String, Map<String, String>> configMaps = getConfigMap();
		List<ConnConf.Builder> confs = new ArrayList<ListenerConf.ConnConf.Builder>();
		for (String preGroup : configMaps.keySet()) {
			Map<String, String> map = configMaps.get(preGroup);
			Builder configMap = configMap(preGroup, map);
			confs.add(configMap);
		}
		return confs;
	}

	public static String getColHiskey(String db, String tb) {
		String key = String.format("%s|%s", db, tb).toLowerCase();
		return key;
	}

}
